14. Functions; Comments

Suppose we want, as part of a larger program, to count the occurrences of the ascii characters in some input text. Let us also map illegal characters (those with value>127 or <0) into one pile. Since this is presumably an isolated part of the program, good practice dictates making it a separate function. Here is one way:

main( ) 

int hist[129];
/* 128 legal chars + 1 illegal group */

...

count(hist, 128); /* count the letters into hist */

printf( ... ); /* comments look like this; use them */

... /* anywhere blanks, tabs or newlines could appear */

count(buf, size)

int size, buf[ ]; 

int i, c;

for( i=0; i<=size; i++ )

buf[i] = 0; 

/* set buf to zero */

while( (c=getchar( )) != ‘\0’ )  /* read til eof */

if( c > size || c < 0 )

c = size; /* fix illegal input */

buf[c]++;

return;

We have already seen many examples of calling a function, so let us concentrate on how to define one. Since count has two arguments, we need to declare them, as shown, giving their types, and in the case of buf, the fact that it is an array. The declarations of arguments go between the argument list and the opening `‘. There is no need to specify the size of the array buf, for it is defined outside of count.

The return statement simply says to go back to the calling routine. In fact, we could have omitted it, since a return is implied at the end of a function.

What if we wanted count to return a value, say the number of characters read? The return statement allows for this too:

int i, c, nchar;

nchar = 0;

...

while( (c=getchar( )) != ‘\0’ ) 

if( c > size || c < 0 )

c = size;

buf[c]++;

nchar++;

return(nchar);

Any expression can appear within the parentheses. Here is a function to compute the minimum of two integers:

min(a, b)

int a, b; 

return( a < b ? a : b );

To copy a character array, we could write the function

strcopy(s1, s2) /* copies s1 to s2 */

char s1[ ], s2[ ]; 

int i;

for( i = 0; (s2[i] = s1[i]) != ‘\0’; i++ );

As is often the case, all the work is done by the assignment statement embedded in the test part of the for. Again, the declarations of the arguments s1 and s2 omit the sizes, because they don’t matter to strcopy. (In the section on pointers, we will see a more efficient way to do a string copy.)

There is a subtlety in function usage which can trap the unsuspecting Fortran programmer. Simple variables (not arrays) are passed in C by ``call by value’’, which means that the called function is given a copy of its arguments, and doesn’t know their addresses. This makes it impossible to change the value of one of the actual
input arguments.

There are two ways out of this dilemma. One is to make special arrangements to pass to the function the address of a variable instead of its value. The other is to make the variable a global or external variable, which is known to each function by its name. We will discuss both possibilities in the next few sections.